/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2013        */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be        */
/* attached to the FatFs via a glue function rather than modifying it.   */
/* This is an example of glue functions to attach various exsisting      */
/* storage control module to the FatFs module with a defined API.        */
/*-----------------------------------------------------------------------*/

#include "diskio.h"		/* FatFs lower layer API */
//#include "usbdisk.h"	/* Example: USB drive control */
//#include "atadrive.h"	/* Example: ATA drive control */
//#include "sdcard.h"		/* Example: MMC/SDC contorl */
#include "platform_config.h"

/* Definitions of physical drive number for each media */
#define ATA		0
#define MMC		1
#define USB		2


/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */
/*-----------------------------------------------------------------------*/

DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber (0..) */
)
{
	//DSTATUS stat;
	//int result;


	//return STA_NOINIT;
	return RES_OK;
}



/*-----------------------------------------------------------------------*/
/* Get Disk Status                                                       */
/*-----------------------------------------------------------------------*/
extern uint32_t Mass_Memory_Size[2];
extern uint32_t Mass_Block_Size[2];
extern uint32_t Mass_Block_Count[2];
DSTATUS disk_status (
	BYTE pdrv		/* Physical drive nmuber (0..) */
)
{
	//DSTATUS stat;
	//int result;
	MAL_GetStatus(0);

	//return STA_NOINIT;
	return RES_OK;
}



/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/

DRESULT disk_read (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE *buff,		/* Data buffer to store read data */
	DWORD sector,	/* Sector address (LBA) */
	UINT count		/* Number of sectors to read (1..128) */
)
{
	//DRESULT res;
	//int result;

	if(count==1)
	{
		MAL_Read(0, sector<<9, buff, 512);
	}
	else
	{
		do{
			MAL_Read(0, sector<<9, buff, 512);
			sector++;
			buff+=512;
		}while(--count);
	}
	return RES_OK;
	//return RES_PARERR;
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */
/*-----------------------------------------------------------------------*/

#if _USE_WRITE
DRESULT disk_write (
	BYTE pdrv,			/* Physical drive nmuber (0..) */
	const BYTE *buff,	/* Data to be written */
	DWORD sector,		/* Sector address (LBA) */
	UINT count			/* Number of sectors to write (1..128) */
)
{
	//DRESULT res;
	//int result;

	if(count==1)
	{
		MAL_Write(0, sector<<9, buff, 512);
	}
	else
	{
		do{
			MAL_Write(0, sector<<9,buff, 512);
			sector++;
			buff+=512;
		}while(--count);					
	}
	return RES_OK;
	//return RES_PARERR;
}
#endif


/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */
/*-----------------------------------------------------------------------*/

#if _USE_IOCTL
DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
	DRESULT res;

	switch (cmd) {
		case CTRL_SYNC :		/* Make sure that no pending write process */
			res = RES_OK;
			break;
		case GET_SECTOR_COUNT :	/* Get number of sectors on the disk (DWORD) */
			*(DWORD*)buff = (DWORD)(32*(1024*1024/512));//32MB flash			
			res = RES_OK;
			break;
		case GET_SECTOR_SIZE :	/* Get R/W sector size (WORD) */
			*(WORD*)buff = 512;
			res = RES_OK;
			break;
		case GET_BLOCK_SIZE :	/* Get erase block size in unit of sector (DWORD) */
			*(DWORD*)buff = 1;	//for Erase
			res = RES_OK;
			break;
		default:
			res = RES_PARERR;
	}
	return res;
}
#endif

DWORD get_fattime(void){
		return ((2012UL-1980) << 25) /* Year = 2012 */  
		| (11UL << 21) /* Month = 11 */  
		| (2UL << 16) /* Day = 2 */  
		| (15U << 11) /* Hour = 15 */  
		| (12U << 5) /* Min = 12 */  
		| (24U >> 1) /* Sec = 24 */  
		;
}
